﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Fortune.Log;
using UnityEngine;
using Random = UnityEngine.Random;

namespace Fortune.Exporter
{
    public class IconExporter
    {
        private static readonly FortuneLogger logger = FortuneLogger.newInstance(typeof(IconExporter));

        private const string OUTPUT_DIR = @"D:\Fortune\icon";

        private static readonly Random random = new Random();


        public static void dumpItemIcon()
        {
            logger.info("item-icon导出开始");
            ItemProto[] itemsDataArray = LDB.items.dataArray;
            int length = itemsDataArray.Length;

            const int step = 20;
            int start = 0;
            int end = step;
            int count = 0;

            while (start < length)
            {
                if (end > length)
                {
                    end = length;
                }

                ParallelLoopResult loopResult = Parallel.For(start, end, index =>
                {
                    ItemProto proto = itemsDataArray[index];
                    dumpAsPNG(proto.iconSprite, string.IsNullOrWhiteSpace(proto.IconPath)?"item\\"+proto.ID:proto.IconPath);
                    Interlocked.Increment(ref count);
                });
                
                while (!loopResult.IsCompleted)
                {
                    Thread.Sleep(1000);
                }

                start += step;
                end += step;
            }
            logger.info($"共写入{count}/{length}个item icon");
        }
        
        public static void dumpVeinIcon()
        {
            logger.info("vein-icon导出开始");

            VeinProto[] veinProtos = LDB.veins.dataArray;
            int length = veinProtos.Length;

            const int step = 20;
            int start = 0;
            int end = step;
            int count = 0;

            while (start < length)
            {
                if (end > length)
                {
                    end = length;
                }

                ParallelLoopResult loopResult = Parallel.For(start, end, index =>
                {
                    VeinProto proto = veinProtos[index];
                    dumpAsPNG(proto.iconSprite, string.IsNullOrWhiteSpace(proto.IconPath)?"vein\\"+proto.ID:proto.IconPath);
                    Interlocked.Increment(ref count);
                });
                
                while (!loopResult.IsCompleted)
                {
                    Thread.Sleep(1000);
                }

                start += step;
                end += step;
            }
            logger.info($"共写入{count}/{length}个vein icon");
        }
        
        public static void dumpRecipeIcon()
        {
            logger.info("recipe-icon导出开始");

            RecipeProto[] recipeProtos = LDB.recipes.dataArray;
            int length = recipeProtos.Length;

            const int step = 20;
            int start = 0;
            int end = step;
            int count = 0;

            while (start < length)
            {
                if (end > length)
                {
                    end = length;
                }

                ParallelLoopResult loopResult = Parallel.For(start, end, index =>
                {
                    RecipeProto proto = recipeProtos[index];
                    dumpAsPNG(proto.iconSprite, string.IsNullOrWhiteSpace(proto.IconPath)?"recipe\\"+proto.ID:proto.IconPath);
                    Interlocked.Increment(ref count);
                });
                
                while (!loopResult.IsCompleted)
                {
                    Thread.Sleep(1000);
                }

                start += step;
                end += step;
            }
            logger.info($"共写入{count}/{length}个recipe icon");
        }
        public static void dumpTechIcon()
        {
            logger.info("tech-icon导出开始");

            TechProto[] protos = LDB.techs.dataArray;
            int length = protos.Length;

            const int step = 20;
            int start = 0;
            int end = step;
            int count = 0;

            while (start < length)
            {
                if (end > length)
                {
                    end = length;
                }

                ParallelLoopResult loopResult = Parallel.For(start, end, index =>
                {
                    TechProto proto = protos[index];
                    dumpAsPNG(proto.iconSprite, string.IsNullOrWhiteSpace(proto.IconPath)?"tech\\"+proto.ID:proto.IconPath);
                    Interlocked.Increment(ref count);
                });
                
                while (!loopResult.IsCompleted)
                {
                    Thread.Sleep(1000);
                }

                start += step;
                end += step;
            }
            logger.info($"共写入{count}/{length}个tech icon");
        }
        public static void dumpAchievementIcon()
        {
            logger.info("achievement-icon导出开始");

            AchievementProto[] protos = LDB.achievements.dataArray;
            int length = protos.Length;

            const int step = 20;
            int start = 0;
            int end = step;
            int count = 0;

            while (start < length)
            {
                if (end > length)
                {
                    end = length;
                }

                ParallelLoopResult loopResult = Parallel.For(start, end, index =>
                {
                    AchievementProto proto = protos[index];
                    dumpAsPNG(proto.iconSprite, string.IsNullOrWhiteSpace(proto.IconPath)?"个achievement\\"+proto.ID:proto.IconPath);
                    Interlocked.Increment(ref count);
                });
                
                while (!loopResult.IsCompleted)
                {
                    Thread.Sleep(1000);
                }

                start += step;
                end += step;
            }
            logger.info($"共写入{count}/{length}个achievement icon");
        }
        
        public static void dumpMilestoneIcon()
        {
            logger.info("milestone-icon导出开始");

            MilestoneProto[] protos = LDB.milestones.dataArray;
            int length = protos.Length;

            const int step = 20;
            int start = 0;
            int end = step;
            int count = 0;

            while (start < length)
            {
                if (end > length)
                {
                    end = length;
                }

                ParallelLoopResult loopResult = Parallel.For(start, end, index =>
                {
                    MilestoneProto proto = protos[index];
                    dumpAsPNG(proto.iconSprite, string.IsNullOrWhiteSpace(proto.IconPath)?"milestone\\"+proto.ID:proto.IconPath);
                    Interlocked.Increment(ref count);
                });
                
                while (!loopResult.IsCompleted)
                {
                    Thread.Sleep(1000);
                }

                start += step;
                end += step;
            }
            logger.info($"共写入{count}/{length}个milestone icon");
        }
        
        private static void dumpAsPNG(Sprite sprite, string iconPath)
        {
            byte[] data = sprite.texture.EncodeToPNG();
            string filePath = Path.Combine(OUTPUT_DIR, iconPath + ".png").Replace("/", @"\");
            if (File.Exists(filePath))
            {
                logger.info($"文件已存在，跳过: ${filePath}");
                return;
            }
            
            string dir = filePath.Substring(0, filePath.LastIndexOf('\\'));
            Directory.CreateDirectory(dir);
            FileStream fileStream = File.Create(filePath);
            BinaryWriter binaryWriter = new BinaryWriter(fileStream);
            binaryWriter.Write(data);
            binaryWriter.Close();
        }
    }
}